﻿using log4net;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MessageQuque.Common
{
    public static class Logger
    {
        #region .ctors
        static Logger()
        {
            //XmlConfigurator.Configure();
            log4net.Config.XmlConfigurator.Configure(
               new FileInfo(
                   Path.Combine(
                       AppDomain.CurrentDomain.BaseDirectory,
                       "log4net.config")));
        }

        /// <summary>
        /// log4net Logger
        /// </summary>
        static readonly ILog _logger = LogManager.GetLogger("DefaultLogger");
        static readonly ILog _error_logger = LogManager.GetLogger("ErrorLogger");
        static readonly ILog _info_logger = LogManager.GetLogger("InfoLogAppender");
        static readonly ILog _debug_logger = LogManager.GetLogger("DebugLogAppender");

        #endregion

        /// <summary>
        /// 将错误信息写入文件
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="message">错误信息</param>
        /// <param name="exception">异常对象</param>
        private static void LogError(this ILog logger, object message, Exception exception)
        {
            var sb = new StringBuilder();
            sb.AppendFormat("{0}<br/>", message);
            sb.AppendFormat("Source：{0}<br/>", exception.Source);
            sb.AppendFormat("StackTrace：{0}<br/>", exception.StackTrace);
            StackTrace(exception, ref sb);
            logger.Error(sb.ToString());
            logger.ErrorFormat("{0}<br/>", exception);
        }

        /// <summary>
        /// 将错误信息写入文件
        /// </summary>
        /// <param name="logger"></param>
        /// <param name="message">错误信息</param>
        private static void LogError(this ILog logger, object message)
        {
            var sb = new StringBuilder();
            if (message.GetType().Equals(typeof(Exception)))
            {
                var exception = message as Exception;
                sb.AppendFormat("{0}<br/>", exception.Message);
                sb.AppendFormat("Source：{0}<br/>", exception.Source);
                sb.AppendFormat("StackTrace：{0}<br/>", exception.StackTrace);
                StackTrace(exception, ref sb);
            }

            logger.Error(sb.ToString());
            logger.ErrorFormat("{0}<br/>", message);
        }

        /// <summary>
        /// 将错误信息写入缓冲区。
        /// </summary>
        /// <param name="e">异常对象</param>
        /// <param name="sb">StringBuilder</param>
        private static void StackTrace(this Exception e, ref StringBuilder sb)
        {
            try
            {
                var st = new StackTrace(e);
                string source = st.GetFrame(0).GetMethod().DeclaringType.FullName + "." + st.GetFrame(0).GetMethod().Name + "()";
                sb.Append("<br/>");
                sb.Append("StackTrace: <br/>");
                sb.AppendFormat("//------------- function:{0}  {1}------------//<br/>", source, DateTime.Now.ToString());
                sb.Append(e.Source + ":" + e.Message + "<br/>");
                sb.Append(e.StackTrace);
                sb.Append("<br/>");
                sb.Append(e.TargetSite.Name);
                sb.Append("<br/>Errors:<br/>");

                if (e.InnerException != null)
                    StackTrace(e.InnerException, ref sb);
            }
            catch
            {
            }
        }

        /// <summary>
        /// 记录级别为[Debug]的日志信息
        /// </summary>
        /// <param name="message">日志信息</param>
        public static void Debug(object message)
        {
#if DEBUG
            _debug_logger.Debug(message);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(message);
#endif
        }

        /// <summary>
        /// 记录级别为[Debug]的日志信息
        /// </summary>
        /// <param name="message">日志信息</param>
        /// <param name="exception">异常信息</param>
        public static void Debug(object message, Exception exception)
        {
#if DEBUG
            _debug_logger.Debug(message, exception);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(exception.ToString());
#endif
        }

        /// <summary>
        /// 记录级别为[Error]的日志信息
        /// </summary>
        /// <param name="message">日志信息</param>
        public static void Error(object message)
        {
            _error_logger.LogError(message);
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(message.ToString());
        }

        /// <summary>
        /// 记录级别为[Error]的日志信息
        /// </summary>
        /// <param name="message">日志信息</param>
        /// <param name="exception">异常信息</param>
        public static void Error(object message, Exception exception)
        {
            _error_logger.LogError(message, exception);
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(exception.ToString());
        }


        /// <summary>
        /// 记录级别为[Fatal]的日志信息
        /// </summary>
        /// <param name="exception">异常信息</param>
        public static void Fatal(object message)
        {
            _error_logger.Fatal(message);
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(message.ToString());
        }

        /// <summary>
        /// 记录级别为[Fatal]的日志信息
        /// </summary>
        /// <param name="message">日志信息</param>
        /// <param name="exception">异常信息</param>
        public static void Fatal(object message, Exception exception)
        {
            _logger.Fatal(message, exception);
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(exception.ToString());
        }

        /// <summary>
        /// 记录级别为[Info]的日志信息
        /// </summary>
        /// <param name="exception">异常信息</param>
        public static void Info(object message)
        {
            _info_logger.Info(message);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(message.ToString());
        }

        /// <summary>
        /// 记录级别为[Info]的日志信息
        /// </summary>
        /// <param name="message">日志信息</param>
        /// <param name="exception">异常信息</param>
        public static void Info(object message, Exception exception)
        {
            _info_logger.Info(message, exception);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(exception.ToString());
        }

        /// <summary>
        /// 记录级别为[Warn]的日志信息
        /// </summary>
        /// <param name="message">日志信息</param>
        public static void Warn(object message)
        {
            _logger.Warn(message);
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(message.ToString());
        }

        /// <summary>
        /// 记录级别为[Warn]的日志信息
        /// </summary>
        /// <param name="message">日志信息</param>
        /// <param name="exception">异常信息</param>
        public static void Warn(object message, Exception exception)
        {
            _logger.Warn(message, exception);
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(exception.ToString());
        }
    }
}
